﻿using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using élénkPróbája.extentions;
using élénkPróbája.Test.dto;
using élénkPróbája.Test.extention;
using élénkPróbája.validators;

namespace élénkPróbája.Test
{
    [TestClass]
    public class EqualValidatorTester
    {
        public EqualValidatorTester()
        {
            CultureScope.SetDefaultCulture();
        }

        [TestMethod]
        public void When_the_objects_are_equal_validation_should_succeed()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal("Foo") };
            var result = validator.Validate(new Company() { Name = "Foo" });

            result.IsValid.ShouldBeTrue();
        }
        [TestMethod]
        public void When_the_objects_are_not_equal_validation_should_fail()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal("Foo") };
            var result = validator.Validate(new Company() { Name = "Bar" });

            result.IsValid.ShouldBeFalse();
        }
        [TestMethod]
        public void When_validation_fails_the_error_should_be_set()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal("Foo") };
            var result = validator.Validate(new Company() { Name = "Bar" });

            result.Errors.Single().ErrorMessage.ShouldEqual("'' should be equal to 'Foo'.");
        }
        [TestMethod]
        public void Should_store_property_to_compare()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal(x => x.PublicName) };
            var descriptor = validator.CreateDescriptor();
            var propertyValidator = descriptor.GetValidatorsForMember("Name").Cast<EqualValidator>().Single();

#if CoreCLR
			propertyValidator.MemberToCompare.ShouldEqual(typeof (Company).GetRuntimeProperty("PublicName"));
#else
            propertyValidator.MemberToCompare.ShouldEqual(typeof(Company).GetProperty("PublicName"));
#endif
        }
        [TestMethod]
        public void Should_store_comparison_type()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal("Foo") };
            var descriptor = validator.CreateDescriptor();
            var propertyValidator = descriptor.GetValidatorsForMember("Name").Cast<EqualValidator>().Single();

            propertyValidator.Comparison.ShouldEqual(Comparison.Equal);
        }
        [TestMethod]
        public void Validates_against_property()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal(x => x.Name) };
            var result = validator.Validate(new Company() { Name = "foo", PublicName = "foo" });
            result.IsValid.ShouldBeTrue();
        }
        [TestMethod]
        public void Should_succeed_on_case_insensitive_comparison()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal("FOO", StringComparer.OrdinalIgnoreCase) };
            var result = validator.Validate(new Company() { Name = "foo" });

            result.IsValid.ShouldBeTrue();
        }
        [TestMethod]
        public void Should_succeed_on_case_insensitive_comparison_using_expression()
        {
            var validator = new TestValidator { v => v.RuleFor(x => x.Name).Equal(x => x.PublicName, StringComparer.OrdinalIgnoreCase) };
            var result = validator.Validate(new Company() { Name = "foo", PublicName = "FOO" });

            result.IsValid.ShouldBeTrue();
        }
    }
}
